﻿using System;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using System.ServiceModel;
using System.Windows;
using PanoramaTestApp.Model;
using PanoramaTestApp.PcInfoServiceReference;

namespace PanoramaTestApp.ViewModels
{
    public class MainViewModel : INotifyPropertyChanged, IFormatProvider
    {

        public MainViewModel()
        {
           this.Items = new ObservableCollection<ItemViewModel>();
           this.GegucktItems = new ObservableCollection<ItemViewModel>();
           this.MarkedItems = new ObservableCollection<ItemViewModel>();

           GlobalSettings.Default.PropertyChanged += new PropertyChangedEventHandler(DefaultPropertyChangedEventHandler);
        }

        private void DefaultPropertyChangedEventHandler(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "ServerAddress")
            {
                NotifyPropertyChanged("ServerDescription");
            }
        }

        /// <summary>
        /// A collection for ItemViewModel objects.
        /// </summary>
        public ObservableCollection<ItemViewModel> Items { get; private set; }
        public ObservableCollection<ItemViewModel> GegucktItems { get; private set; }
        public ObservableCollection<ItemViewModel> MarkedItems { get; private set; }
      
        private bool _isComputerOn = true;
        private bool _isServiceOnline;
        private TimeSpan _pcStartUpTime;
        private DateTime _serviceStartUpTime;
        private DateTime _lastShutdownTime;
        private bool _isEnabled = true;

        public bool IsDataLoaded
        {
            get;
            set;
        }

        /// <summary>
        /// Creates and adds a few ItemViewModel objects into the Items collection.
        /// </summary>
        public void LoadData()
        {
            //Application.Current.Resources["BooleanPQ"] = false;

            this.IsEnabled = false;

            MainPage.CheckOnlineStatus(GlobalSettings.Default.ServerHttpAddress);

            try
            {
                var client = new PcInfoServiceClient();
                client.Endpoint.Address = new EndpointAddress(GlobalSettings.Default.ServerAddress);
                
                client.GetFileInformationCompleted += (sender, e) =>
                                                          {
                                                              if (e.Result != null)
                                                              {
                                                                  this.Items.Clear();
                                                                  for (int index = 0; index < e.Result.Count; index++)
                                                                  {
                                                                      var fileEntry = e.Result[index];
                                                                      this.Items.Add(new ItemViewModel()
                                                                                         {
                                                                                             CreationTime =
                                                                                                 fileEntry.CreationTime.
                                                                                                 ToString(),
                                                                                             FileName = fileEntry.Name
                                                                                         });
                                                                  }

                                                                  this.IsDataLoaded = true;
                                                              }
                                                             
                                                              
                                                          };
                client.GetFileInformationAsync();
            }
            catch (FaultException<UserFriendlyError> exception)
            {
                ExceptionOccured(exception);
            }
            catch (Exception exc)
            {
                ExceptionOccured(exc);
            }

            try
            {
                var client = new PcInfoServiceClient();
                client.Endpoint.Address = new EndpointAddress(GlobalSettings.Default.ServerAddress);

                client.GetGeGucktFileInformationCompleted += (sender, e) =>
                {
                    if (e.Result != null)
                    {
                        var results = GetSortedArray(e);

                        this.GegucktItems.Clear();
                        for (int index = 0; index < results.Length; index++)
                        {
                            var fileEntry = results[index];
                            this.GegucktItems.Add(new ItemViewModel()
                            {
                                CreationTime =
                                    fileEntry.CreationTime.
                                    ToString(),
                                FileName = fileEntry.Name,
                                FileEntryCache = fileEntry,
                                IsChecked = false
                            });
                        }

                        this.IsDataLoaded = true;
                    }
                };

                client.GetGeGucktFileInformationAsync();
            }
            catch (FaultException<UserFriendlyError> exception)
            {
                ExceptionOccured(exception);
            }
            catch (Exception exc)
            {
                ExceptionOccured(exc);
            }

            try
            {
                var client = new PcInfoServiceClient();
                client.Endpoint.Address = new EndpointAddress(GlobalSettings.Default.ServerAddress);

                client.GetMarkedLookedFilesCompleted += (sender, e) =>
                {
                    if (e.Result != null)
                    {
                        var results = GetSortedArray(e);

                        this.MarkedItems.Clear();
                        for (int index = 0; index < results.Length; index++)
                        {
                            var fileEntry = results[index];
                            this.MarkedItems.Add(new ItemViewModel()
                            {
                                CreationTime =
                                    fileEntry.CreationTime.
                                    ToString(),
                                FileName = fileEntry.Name,
                                FileEntryCache = fileEntry,
                                IsChecked = false
                            });
                        }

                        this.IsDataLoaded = true;
                    }
                };

                client.GetMarkedLookedFilesAsync();

            }
            catch (FaultException<UserFriendlyError> exception)
            {
                ExceptionOccured(exception);
            }
            catch (Exception exc)
            {
                ExceptionOccured(exc);
            }

            try
            {

                var client = new PcInfoServiceClient();
                client.Endpoint.Address = new EndpointAddress(GlobalSettings.Default.ServerAddress);

                client.GetPCStartUpTimeCompleted += (sender, args) =>
                {
                    PcStartUpTime = args.Result;
                };

                client.GetPCStartUpTimeAsync();
            }
            catch (FaultException<UserFriendlyError> exception)
            {
                ExceptionOccured(exception);
            }
            catch (Exception exc)
            {
                ExceptionOccured(exc);
            }

            try
            {

                var client = new PcInfoServiceClient();
                client.Endpoint.Address = new EndpointAddress(GlobalSettings.Default.ServerAddress);

                client.GetStartUpTimeCompleted += (sender, args) =>
                {
                    ServiceStartUpTime = args.Result;
                };

                client.GetStartUpTimeAsync();
            }
            catch (FaultException<UserFriendlyError> exception)
            {
                ExceptionOccured(exception);
            }
            catch (Exception exc)
            {
                ExceptionOccured(exc);
            }

            try
            {

                var client = new PcInfoServiceClient();
                client.Endpoint.Address = new EndpointAddress(GlobalSettings.Default.ServerAddress);

                client.GetLastSystemShutdownCompleted += (sender, args) =>
                {
                    LastShutdownTime = args.Result;
                    this.IsEnabled = true;
                };

                client.GetLastSystemShutdownAsync();
            }
            catch (FaultException<UserFriendlyError> exception)
            {
                ExceptionOccured(exception);
            }
            catch (Exception exc)
            {
                ExceptionOccured(exc);
            }

            

            this.IsDataLoaded = true;

        }

        private FileEntry[] GetSortedArray(GetMarkedLookedFilesCompletedEventArgs e)
        {
            if (GlobalSettings.Default.UseNameFilter)
                return e.Result.OrderBy(x => x.Name).ToArray();
            return e.Result.OrderBy((x => x.CreationTime)).ToArray();
        }

        private FileEntry[] GetSortedArray(GetGeGucktFileInformationCompletedEventArgs e)
        {
            if(GlobalSettings.Default.UseNameFilter)
                return e.Result.OrderBy(x => x.Name).ToArray();
            return e.Result.OrderBy((x => x.CreationTime)).ToArray();
        }

        public bool IsEnabled
        {
            get { return _isEnabled; }
            set
            {
                _isEnabled = value;
                NotifyPropertyChanged("IsEnabled");
            }
        }

        private void ExceptionOccured(Exception exc)
        {
            MessageBox.Show(exc.Message, "Exception occured", MessageBoxButton.OK);
        }

        public DateTime ServiceStartUpTime
        {
            get { return _serviceStartUpTime; }
            set
            {
                _serviceStartUpTime = value;
                NotifyPropertyChanged("ServiceStartUpTime");
                NotifyPropertyChanged("ServiceStartUpTimeDescription");
            }
        }

        public string ServiceStartUpTimeDescription
        {
            get { return ServiceStartUpTime.ToString("dd-MMM-yyyy hh:mm tt", DateTimeFormatInfo.InvariantInfo); }
        }

        public DateTime LastShutdownTime
        {
            get { return _lastShutdownTime; }
            set
            {
                _lastShutdownTime = value;
                NotifyPropertyChanged("LastShutdownTime");
                NotifyPropertyChanged("LastShutdownTimeDescription");
            }
        }

        public string LastShutdownTimeDescription
        {
            get { return LastShutdownTime.ToString("dd-MMM-yyyy hh:mm tt", DateTimeFormatInfo.InvariantInfo); }
        }

        private void ExceptionOccured(FaultException<UserFriendlyError> exception)
        {
            MessageBox.Show(exception.Message, "Exception occured", MessageBoxButton.OK);
        }

        public string ComputerShutdown
        {
            get
            {
                if (_isComputerOn)
                    return "ready/on";

                return "shutdown/off";
            }
        }

        public bool IsComputerOn
        {
            get
            {
                return _isComputerOn;
            }
            set 
            {
                try
                {
                    if (value)
                    {
                        var client = new PcInfoServiceClient();
                        client.Endpoint.Address = new EndpointAddress(GlobalSettings.Default.ServerAddress);

                        client.CancelShutDownAsync();
                        client.CancelShutDownCompleted += (sender, args) =>
                        {
                            if (!args.Cancelled)
                                _isComputerOn = value;

                            NotifyPropertyChanged("ÏsComputerOn");
                            NotifyPropertyChanged("ComputerShutdown");
                        };
                    }
                    else
                    {
                        var client = new PcInfoServiceClient();
                        client.Endpoint.Address = new EndpointAddress(GlobalSettings.Default.ServerAddress);

                        client.ShutDownAsync();
                        client.ShutDownCompleted += (sender, args) =>
                        {
                            if (!args.Cancelled)
                                _isComputerOn = value;

                            NotifyPropertyChanged("ÏsComputerOn");
                            NotifyPropertyChanged("ComputerShutdown");
                        };
                    }
                }
                catch (FaultException<UserFriendlyError> exc)
                {
                    ExceptionOccured(exc);
                }
                catch (Exception exc)
                {
                    ExceptionOccured(exc);
                }                              

            }
        }

        public bool IsServiceOnline
        {
            get
            {
                try
                {
                    var client = new PcInfoServiceClient();
                    client.Endpoint.Address = new EndpointAddress(GlobalSettings.Default.ServerAddress);

                    client.IsShutdownRequestedCompleted += (sender, args) =>
                                                               {
                                                                   _isServiceOnline = args.Result;
                                                               };
                    client.IsShutdownRequestedAsync();
                }
                catch (Exception exc)
                {
                    ExceptionOccured(exc);
                }
                return _isServiceOnline;
            }
            
        }

        public TimeSpan PcStartUpTime
        {
            get
            {
                return _pcStartUpTime;
            }
            set 
            { 
                _pcStartUpTime = value;
                NotifyPropertyChanged("PcStartUpTime");
                NotifyPropertyChanged("PcStartUpTimeDescription");
            }
        }

        public string PcStartUpTimeDescription
        {
            get
            {
                return string.Format("{0}h {1}min {2}sec", _pcStartUpTime.Hours, _pcStartUpTime.Minutes, _pcStartUpTime.Seconds);
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (null != handler)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public void DeleteSelectedData()
        {
            try
            {
                var items = from item in GegucktItems
                            where item.IsChecked
                            select item.FileEntryCache;

                var client = new PcInfoServiceClient();
                client.Endpoint.Address = new EndpointAddress(GlobalSettings.Default.ServerAddress);

                client.DeleteFileEntriesCompleted += (sender, args) =>
                                                            {
                                                                this.LoadData();
                                                            };

                var entries = new ObservableCollection<FileEntry>();

                foreach (var fileEntry in items)
                {
                    entries.Add(fileEntry);
                }

                client.DeleteFileEntriesAsync(entries);
            }
            catch (FaultException<UserFriendlyError> error)
            {
                ExceptionOccured(error);
            }
            catch(Exception)
            {
                MessageBox.Show("Exception occured while deleting data");
            }
        }


        public void MoveSelectedData()
        {
            try
            {
                var items = from item in GegucktItems
                            where item.IsChecked
                            select item.FileEntryCache;

                var client = new PcInfoServiceClient();
                client.Endpoint.Address = new EndpointAddress(GlobalSettings.Default.ServerAddress);
                
                client.MarkFilesAsLookedCompleted += (sender, args) =>
                {
                    this.LoadData();
                };

                var entries = new ObservableCollection<FileEntry>();

                foreach (var fileEntry in items)
                {
                    entries.Add(fileEntry);
                }

                client.MarkFilesAsLookedAsync(entries);
            }
            catch (FaultException<UserFriendlyError> error)
            {
                ExceptionOccured(error);
            }
            catch (Exception)
            {
                MessageBox.Show("Exception occured while deleting data");
            }
        }

        public string ServerDescription
        {
            get
            {
                if (GlobalSettings.Default.ServerAddress == GlobalSettings.Default.InternetAddress)
                    return "Internet access";
                return "Local access";
            }
          
        }

        public object GetFormat(Type formatType)
        {
            throw new NotImplementedException();
        }
    }
}